package com.treasure.mall.biz.service.core.life.impl;

import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.life.ShopBusinessDTO;
import com.treasure.mall.biz.dto.life.ShopSaveDTO;
import com.treasure.mall.biz.dto.life.ShopSearchCondition;
import com.treasure.mall.biz.entity.embeddable.ReceivingInfo_;
import com.treasure.mall.biz.entity.life.*;
import com.treasure.mall.biz.mapstruct.LifeShopMapStruct;
import com.treasure.mall.biz.repository.life.*;
import com.treasure.mall.biz.service.core.life.LifeShopService;
import com.treasure.mall.biz.service.core.life.ShopReservationRecordsService;
import com.treasure.mall.biz.vo.life.ShopBusinessVO;
import com.treasure.mall.biz.vo.life.ShopCityVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * <p>
 * +---------------------------------------------------------
 * * @package: com.treasure.mall.biz.service.core.life.impl
 * * @author: guomw (guomwchen@foxmail.com)
 * * @date: 2020/10/13 2:38 下午
 * * @since: V1.0.0
 * +---------------------------------------------------------
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 * 
 */
@Service
public class LifeShopServiceImpl extends AbstractSearchableCrudService<ShopPO, Long> implements LifeShopService {

    private ShopRepository shopRepository;

    @Autowired
    private ShopBusinessTagsRepository tagsRepository;
    @Autowired
    private ShopBusinessScopeRepository scopeRepository;
    @Autowired
    private ShopReservationRecordsService reservationRecordsService;
    @Autowired
    private RelShopScopeRepository relShopScopeRepository;
    @Autowired
    private RelShopTagsRepository relShopTagsRepository;

    protected LifeShopServiceImpl(ShopRepository repository) {
        super(repository);
        shopRepository = repository;
    }

    @Override
    protected SpecificationAndSort<ShopPO> specificationAndSort(BaseSearchDTO searchDTO) {
        ShopSearchCondition condition = (ShopSearchCondition) searchDTO;
        Specification<ShopPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(cb.equal(root.get(ShopPO_.deleted), false));

            if (StringUtils.isNotBlank(condition.getKeyword())) {
                predicates.add(cb.like(root.get(ShopPO_.title), likeAll(condition.getKeyword())));
            }
            //筛选掌眼
            if (condition.isPalmEyeService()) {
                predicates.add(cb.equal(root.get(ShopPO_.palmEyeService), true));
            }
            //筛选修复
            if (condition.isRepairService()) {
                predicates.add(cb.equal(root.get(ShopPO_.repairService), true));
            }
            //筛选学院
            if (condition.isSchoolService()) {
                predicates.add(cb.equal(root.get(ShopPO_.schoolService), true));
            }
            //是否过滤冻结状态
            if (condition.getDisabled() != null) {
                predicates.add(cb.equal(root.get(ShopPO_.disabled), condition.getDisabled()));
            }

            if (condition.getRecommend() != null) {
                predicates.add(cb.equal(root.get(ShopPO_.recommend), condition.getRecommend()));
            }


            if (StringUtils.isNotBlank(condition.getCityName())) {
                predicates.add(cb.equal(root.get(ShopPO_.shopAddress).get(ReceivingInfo_.countyName), condition.getCityName()));
            }
            if (StringUtils.isNotBlank(condition.getCityCode())) {
                predicates.add(cb.equal(root.get(ShopPO_.shopAddress).get(ReceivingInfo_.districtCode), condition.getCityCode()));
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public ShopPO save(BaseSaveDTO saveDTO) {
        return null;
    }

    @Override
    public Long saveShop(ShopSaveDTO dto) {
        ShopPO po = LifeShopMapStruct.INSTANCE.shopDto2po(dto);
        po = save(po);
        //删除店铺标签
        relShopTagsRepository.deleteByShopId(po.getId());
        relShopScopeRepository.deleteByShopId(po.getId());
        //更新新标签
        for (Long tagId : dto.tagIds()) {
            RelShopTagsPO tagsPO = new RelShopTagsPO();
            tagsPO.setTagsId(tagId);
            tagsPO.setShopId(po.getId());
            relShopTagsRepository.save(tagsPO);
        }
        for (Long scopeId : dto.scopeIds()) {
            RelShopScopePO tagsPO = new RelShopScopePO();
            tagsPO.setScopeId(scopeId);
            tagsPO.setShopId(po.getId());
            relShopScopeRepository.save(tagsPO);
        }
        return po.getId();
    }

    /**
     * 获取经营范围
     *
     * @return
     */
    @Override
    public List<ShopBusinessVO> listByScope() {
        return LifeShopMapStruct.INSTANCE.scopesPos2vos(scopeRepository.findAll());
    }

    /**
     * 获取业务标签
     *
     * @return
     */
    @Override
    public List<ShopBusinessVO> listByTags() {
        return LifeShopMapStruct.INSTANCE.tagsPos2vos(tagsRepository.findAll());
    }

    /**
     * 保存经营范围
     *
     * @param dto
     */
    @Override
    public void saveScope(ShopBusinessDTO dto) {
        ShopBusinessScopePO po = LifeShopMapStruct.INSTANCE.busDtoToScopePo(dto);
        scopeRepository.save(po);
    }

    /**
     * 保存业务标签
     *
     * @param dto
     */
    @Override
    public void saveTags(ShopBusinessDTO dto) {
        ShopBusinessTagsPO po = LifeShopMapStruct.INSTANCE.busDtoToTagsPo(dto);
        tagsRepository.save(po);
    }

    /**
     * 获取预约记录
     *
     * @param page
     * @param size
     * @param searchDTO
     * @return
     */
    @Override
    public Page<ShopReservationRecordsPO> findAllRecord(int page, int size, BaseSearchDTO searchDTO) {
        return reservationRecordsService.findAll(page, size, searchDTO);
    }

    /**
     * 冻结或启用门店
     *
     * @param shopId
     */
    @Override
    public void disabledToggle(Long shopId) {
        ShopPO po = findById(shopId);
        if (po != null) {
            po.setDisabled(po.isDisabled());
            save(po);
        }
    }

    /**
     * 添加预约记录
     *
     * @param userId
     * @param shopId
     */
    @Override
    public void insertRecord(Long userId, Long shopId) {
        reservationRecordsService.insertRecord(userId, shopId);
    }

    /**
     * 获取店铺城市
     *
     * @param type 0 掌眼专区城市  1修复专区城市
     * @return
     */
    @Override
    public List<ShopCityVO> findCity(int type) {
        List<ShopCityVO> cityList = new ArrayList<>();
        List<ShopPO> list = null;
        if (type == 0) {
            list = shopRepository.findByPalmEyeServiceIsTrue();
        }
        if (type == 1) {
            list = shopRepository.findByRepairServiceIsTrue();
        }
        if (list != null && list.size() > 0) {
            list.forEach(item -> {
                if (cityList.stream().filter(r -> r.getId().toString().equals(item.getShopAddress().getCityCode())).findFirst().orElse(null) == null) {
                    cityList.add(new ShopCityVO(Integer.valueOf(item.getShopAddress().getCityCode()), item.getShopAddress().getCityName()));
                }
            });
            list.forEach(item -> {
                cityList.forEach(r -> {
                    if (r.getId().toString().equals(item.getShopAddress().getCityCode())) {
                        List<ShopCityVO> ls = r.getChildren();
                        if (ls.stream().filter(x -> x.getId().toString().equals(item.getShopAddress().getDistrictCode())).findFirst().orElse(null) == null) {
                            ls.add(new ShopCityVO(Integer.valueOf(item.getShopAddress().getDistrictCode()), item.getShopAddress().getCountyName()));
                            r.setChildren(ls);
                        }
                    }
                });
            });
        }
        return cityList;
    }
}
